-- ======================================
-- 注：批量扣除商品库存lua脚本
-- ======================================

-- 入参key,本次要扣除库存的数据都存这里面
local productKey = KEYS[1];
-- 入参key,定义扣库库存方式。为1时，如果某个商品数量不足，跳过扣除该库存；为2时，如果某个商品数量不足，剩余多少库存就扣多少
-- 示例：某个库存剩余数量为10，现在要求扣库的数量为20。那么扣库方式为1时，不扣除该库存，扣库方式为2时，扣除的数量则为10
local deductionStockType = KEYS[2];
-- 定义扣除库存成功的商品编码
local successProductInfo = '';
-- 定义扣除库存失败的商品编码
local errorProductInfo = '';
-- 从redis中查出要扣库存的数据
local productHashInfoMap = redis.call('HGETALL', productKey);
-- 遍历要扣除库存的商品
for i = 1, #productHashInfoMap, 2 do
    -- 商品编码
    local productUuid = productHashInfoMap[i];
    -- 扣除数量
    local productNum = tonumber(productHashInfoMap[i + 1]);
    local currentNum = redis.call('DECRBY', productUuid, productNum);
    -- 如果扣除库存后，库存数量小于0，执行回滚操作，该商品扣库失败
    if (tonumber(currentNum) < 0) then
        -- 回滚扣库操作
        redis.call('INCRBY', productUuid, productNum)
        -- 判断扣库方式
        if (deductionStockType ~= '3') then
            -- 记录扣库失败的数据
            errorProductInfo = errorProductInfo .. productUuid .. ',' .. productNum .. ';'
        else
            -- 查询剩余多少库存
            local stockNum = redis.call('get', productUuid);
            if (stockNum and stockNum ~= 'nil' and tonumber(stockNum) ~= 0) then
                redis.call('DECRBY', productUuid, tonumber(stockNum));
                -- 记录扣库成功的数据
                successProductInfo = successProductInfo .. productUuid .. ',' .. tonumber(stockNum) .. ';'
            else
                -- 记录扣库失败的数据
                errorProductInfo = errorProductInfo .. productUuid .. ',' .. productNum .. ';'
            end
        end
    else
        -- 记录扣库成功的数据
        successProductInfo = successProductInfo .. productUuid .. ',' .. productNum .. ';'
    end
end
return successProductInfo .. '|' .. errorProductInfo;


